//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#ifndef _ListE_h_
#define _ListE_h_
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include "Node.h"
#include "Node.cpp"
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
class TListE {

  private :

    long              length;

    TNode <T>*        first;
    TNode <T>*        final;

    TNode <T>*        previous;
    TNode <T>*        current;
    TNode <T>*        next;

  protected:

    typedef void      (*TFunctionAction)(TNode <T>*, void*);

    typedef bool      (*TFunctionConditionalB)(TNode <T>*, void*);
    typedef bool      (*TFunctionConditionalBParameters)(TNode <T>*, void*, void*);

    typedef int       (*TFunctionConditionalI)(TNode <T>*, void*);
    typedef double    (*TFunctionConditionalD)(TNode <T>*, void*);

    typedef bool      (*TFunctionConditionalTB)(T*, void*);
    
    void              MixList (TFunctionConditionalB, void*, TListE <T>*);
    void              MixListX (TFunctionConditionalB, void*, TListE <T>*, TListE <T>*, TListE <T>*);

    void              MixList (TFunctionConditionalBParameters, void*, void*, TListE <T>*);
    void              MixListX (TFunctionConditionalBParameters, void*, void*, TListE <T>*, TListE <T>*, TListE <T>*);

    void              MixListByArray (TFunctionConditionalTB, void*, void**, long);
    void              MixListByArrayX (TFunctionConditionalTB, void*, void**, void**, void**, long, long, long);

    TNode <T>*        PosNode (long);
    void              SetCurrent (TNode <T>*);

  public :

    TListE ();
    TListE (T*);
    TListE (TListE <T>*);
    TListE (TListE <T>&);

    ~TListE ();

    void          Add (T*);
    void          AddIni (T*);
    void          AddNode (TNode <T>*);
    void          AddNodeIni (TNode <T>*);

    void          Add (T);
    void          AddIni (T);
    void          AddNode (TNode <T>);
    void          AddNodeIni (TNode <T>);

    void          Delete (long);
    void          Delete (T*);
    void          DeleteCurrent (void);

    void          Insert (T*, long);
    void          InsertBeforeCurrent (T*);
    void          InsertAfterCurrent (T*);

    void          InsertNode (TNode <T>*, long);
    void          InsertNodeBeforeCurrent (TNode <T>*);
    void          InsertNodeAfterCurrent (TNode <T>*);

    T*            Transfer (long);
    T*            TransferCurrent (void);

    TNode <T>*    TransferNode (long);
    TNode <T>*    TransferCurrentNode (void);

    void          TransferAll (void);

    void          Destroy (long);
    void          DestroyCurrent (void);
    
    void          HiddenAll (void);
    void          VisibleAll (void);

    bool          Update (T*, long);

    long          Length (void);

    void          SetPosition (long);
    void          SetInitial (void);
    bool          SetNext (void);
    bool          SetPrevious (void);

    T*            Get (long);
    T*            GetPrevious (void);
    T*            GetCurrent (void);
    T*            GetNext (void);
    T*            GetFirst (void);
    T*            GetFinal (void);

    TNode <T>*    GetNode (long);
    TNode <T>*    GetPreviousNode (void);
    TNode <T>*    GetCurrentNode (void);
    TNode <T>*    GetNextNode (void);
    TNode <T>*    GetFirstNode (void);
    TNode <T>*    GetFinalNode (void);

    static void   ExchangeElement (T*, T*);
    static void   ExchangeNode (TNode <T>*, TNode <T>*);

    void          ExchangeBlocks (long, long, long, long);
    void          ExchangeBlocks (long, long, long);

    void          ForEach (TFunctionAction, void*);
    void          ForEachFrom (TNode <T>*, TFunctionAction, void*);

    T*            FirstOcurrence (TFunctionConditionalB, void*);
    T*            FirstOcurrence (TFunctionConditionalBParameters, void*, void*);
    T*            FirstOcurrenceFrom (TNode <T>*, TFunctionConditionalB, void*);

    long          FirstOcurrencePosition (TFunctionConditionalB, void*);
    
    void          AllOcurrence (TFunctionConditionalB, TListE <T>*, void*);
    void          AllOcurrence (TFunctionConditionalBParameters, TListE <T>*, void*, void*);
    void          AllOcurrenceFrom (TNode <T>*, TFunctionConditionalB, TListE <T>*, void*);

    void          ConsecutiveSubList (TFunctionConditionalB, TListE <T>*, void*);
    void          ConsecutiveSubList (TFunctionConditionalBParameters, TListE <T>*, void*, void*);
    void          CleanConsecutiveSubList (void);

    void          AllOcurrenceCond (TFunctionConditionalI, TListE <T>*, void*);
    void          AllOcurrenceCondFrom (TNode <T>*, TFunctionConditionalI, TListE <T>*, void*);

    void          RepresentativeOcurrencesAfterOrdered (TFunctionConditionalBParameters, TListE <T>*, void*);
    void          RepresentativeOcurrences (TFunctionConditionalBParameters, TListE <T>*, void*);

    long          NumberOcurrence (TFunctionConditionalB, void*);
    long          NumberOcurrence (TFunctionConditionalBParameters, void*, void*);
    long          NumberOcurrenceFrom (TNode <T>*, TFunctionConditionalB, void*);
    long          NumberOcurrenceFrom (TNode <T>*, TFunctionConditionalBParameters, void*, void*);

    void          OrderList (TFunctionConditionalB, void*);

    void          OrderListCentered (TFunctionConditionalD, void*);

    void          OrderListByList (TFunctionConditionalB, TListE <T>*);
    void          OrderListByList (TFunctionConditionalBParameters, TListE <T>*, void*);

    void          QuickSortList (TFunctionConditionalB, void*);
    void          QuickSortList (TFunctionConditionalBParameters, void*, void*);

    void          QuickSortListByArray (TFunctionConditionalTB, void*);
    
    void          CompactListAfterOrdered (TFunctionConditionalB, void*);

    bool          Empty (void);
    bool          Clear (void);

    TListE <T>    operator= (TListE <T>&);

};
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#endif
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
